package com.bims.jreport.pdf.builder;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.bims.jreport.document.DocTemplate;
import com.bims.jreport.pdf.CustomStyle;
import com.bims.jreport.pdf.CustomImgData;
import com.bims.jreport.pdf.fields.BasePdfFormField;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.layout.font.FontProvider;
import com.itextpdf.layout.font.FontSet;
import lombok.Getter;
import lombok.Setter;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * PDF构建上下文
 *
 * @author wangrenjie
 */
@Getter
@Setter
public class BuilderContext {


    //总页数
    private int pageCount;

    /**
     * PDF样式集
     */
    private Map<String, CustomStyle> styleSet;


    /**
     * 图片集
     */
    private Map<String, CustomImgData> imageSet;


    /**
     * 字体集
     */

    private Map<String, PdfFont> fontSet;

    /**
     * 表单域集
     */
    private Map<Integer, Set<BasePdfFormField>> formFieldSet;


    /**
     * 数据绑定集
     */
    private Map<String, String> dataBindSet;


    /**
     * 初始化上下文
     *
     * @param docTemplate
     */
    public BuilderContext(DocTemplate docTemplate, Map<String, PdfFont> fontSet) {
        this.pageCount = docTemplate.getTables().size();
        this.imageSet = docTemplate.fetchImageSet();
        this.styleSet = docTemplate.fetchStyleSet();
        List<String> fontNames = this.styleSet.values().stream().map(CustomStyle::getFontName).collect(Collectors.toList());
        this.fontSet = fontSet.entrySet().stream().filter(f -> fontNames.contains(f.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }


    /**
     * 获得字体提供者
     *
     * @return
     */
    public FontProvider fetchFontProvider() {
        FontSet fontSet = new FontSet();
        this.fontSet.forEach((k, v) -> fontSet.addFont(v.getFontProgram(), PdfEncodings.IDENTITY_H, k));
        return new FontProvider(fontSet);
    }

    /**
     * 获得自定义表单域
     *
     * @param pageIndex 第几页的
     * @return 自定义表单域
     */
    public Set<BasePdfFormField> getFormFields(Integer pageIndex) {
        if (MapUtil.isNotEmpty(formFieldSet) && null != pageIndex) {
            return formFieldSet.get(pageIndex);
        }
        return null;
    }


    /**
     * 获得样式
     *
     * @param styleName
     * @return
     */
    public CustomStyle getStyle(String styleName) {
        if (MapUtil.isNotEmpty(styleSet) && StrUtil.isNotBlank(styleName)) {
            return styleSet.get(styleName);
        }
        return null;
    }


    /**
     * 根据字体名称获得字体
     *
     * @param fontName 字体名称
     * @return PDF  字体
     */
    public PdfFont getFont(String fontName) {
        //TODO 默认字体处理
        if (MapUtil.isNotEmpty(fontSet) && StrUtil.isNotBlank(fontName)) {
            return fontSet.get(fontName);
        }
        return null;
    }


    /**
     * 获得图片数据
     * @param imgName 图片名称
     * @return 图片数据
     */
    public CustomImgData getImageData(String imgName) {
        if (MapUtil.isNotEmpty(imageSet) && StrUtil.isNotBlank(imgName)) {
            return imageSet.get(imgName);
        }
        return null;
    }

    /**
     * 添加数据绑定
     *
     * @param key
     * @param value
     */
    public void addDataBind(String key, String value) {
        if (MapUtil.isEmpty(dataBindSet)) {
            dataBindSet = new HashMap<>();
        }
        dataBindSet.put(key, value);
    }

    /**
     * 添加自定义域
     *
     * @param pageIndex        第几页
     * @param basePdfFormField 自定义表单域
     */
    public void addField(Integer pageIndex, BasePdfFormField basePdfFormField) {
        if (MapUtil.isEmpty(formFieldSet)) {
            formFieldSet = new HashMap<>();
        }
        if (formFieldSet.containsKey(pageIndex)) {
            formFieldSet.get(pageIndex).add(basePdfFormField);
        } else {
            formFieldSet.put(pageIndex, CollUtil.newHashSet(basePdfFormField));
        }
    }
}
